package work

import (
	"context"
	"fmt"
	"go.uber.org/zap"
	"seat-service/initialization"
	"seat-service/model"
	service "seat-service/service/impl"
	"strings"
	"time"
)

const (
	violatePrefix = "violate"
)

var studentService service.StudentService

type DefaultHandler struct{}

func (d *DefaultHandler) Handle(channel, message string) {
	//score := int64(z[0].Score) //需要签到的最晚时间
	//member := z[0].Member.(string)
	//// 计算需要休眠的时间间隔
	//// 转换为时间
	//if score-time.Now().Unix() > 0 {
	//	latestTime := time.Unix(score, 0)
	//	sleepDuration := latestTime.Sub(time.Now())
	//	//fmt.Println("需要休眠", sleepDuration)
	//	// 比如设定10分钟
	//	// 每一个预约项都有一个10分钟后要再次检测这个项.
	//	// ID:1  TIMEUNIX: 2222
	//	// 每次从集合中取出并检测每项的时间戳是否过时了
	//	time.Sleep(sleepDuration) //休眠到需要签到的最晚时间
	//}
	//如果到截至时间还没有签到 , 将该学生添加到违约的list集合中
	memberArr := strings.Split(message, "/")
	//如果还能根据这个memberArr 查询到数据 那就说明这个学生违约了
	exists, err := initialization.Redis.Exists(context.Background(), message).Result()
	if err != nil {
		initialization.SeatLogger.Error("initialization.Redis.Exists(context.Background() , member).Result() is failed", zap.Error(err))
		return
	}

	studentId := memberArr[1] //拿到学生的id
	//修改这条预约状态为违约 根据学生id 和 预约开始的时间
	startTime := memberArr[2] //预约开始时间
	fmt.Println("预约开始时间", startTime)
	if exists == 1 {
		fmt.Println("违约")
		//存在即违约
		initialization.DB.Debug().Model(&model.Reserve{}).Where("student_id = ? and appointment_time_start = ?", studentId, startTime).Update("reserve_status", 2) //修改预约状态
		initialization.Redis.LPush(context.Background(), violatePrefix+"-"+studentId, time.Now().Unix())
		//删除redis中存储的学生的预约信息
		initialization.Redis.Del(context.Background(), message)
		//创建一个list集合,如果该学生违约,插入一次违约记录 , 插入之后检查学生list集合的长度是否大于3
		if initialization.Redis.LLen(context.Background(), violatePrefix+"-"+studentId).Val() >= 3 {
			initialization.SeatLogger.Debug("学生违约" + studentId)
			//禁用该学生两周 并且删除该list集合
			initialization.Redis.Del(context.Background(), violatePrefix+"-"+studentId)
			//修改数据库中的学生状态
			now := time.Now()
			//计算两周后的时间
			twoWeeksLater := now.AddDate(0, 0, 14)
			violateStudentInformation, err := studentService.ViolateStudent(studentId, now, twoWeeksLater)
			if err != nil {
				initialization.SeatLogger.Error("studentService.ViolateStudent(studentId , now , twoWeeksLater) is failed", zap.Error(err))
			}
			initialization.SeatLogger.Info("违约学生信息", zap.Any("violate", violateStudentInformation))
		}
	} else {
		//不存在说明学生已经签到 标记预约记录正常使用即可
		fmt.Println("预约开始时间", startTime)
		initialization.DB.Model(&model.Reserve{}).Where("student_id = ? and appointment_time_start = ?", studentId, startTime).Update("reserve_status", 1) //修改预约状态
	}

}

//func PushReserve(pool *utils.Pool) {
//	// 提交一些任务到协程池
//	for {
//		time.Sleep(time.Second)
//		task := &ReserveTask{
//			redisClient: initialization.Redis,
//			zsetKey:     service.Sign,
//		}
//		pool.Submit(task)
//	}
//}
//
//// ReserveTask 示例任务实现了Task接口
//type ReserveTask struct {
//	redisClient *redis.Client // Redis客户端
//	zsetKey     string        // zset的键
//}
//
//func (r *ReserveTask) Execute() {
//	var z []redis.Z
//	var errZ error
//	z, errZ = r.redisClient.ZPopMin(context.Background(), r.zsetKey).Result()
//	if errZ != nil {
//		fmt.Println(errZ.Error())
//	} else if len(z) == 0 {
//
//	} else {
//
//		score := int64(z[0].Score) //需要签到的最晚时间
//		member := z[0].Member.(string)
//		// 计算需要休眠的时间间隔
//		// 转换为时间
//		if score-time.Now().Unix() > 0 {
//			latestTime := time.Unix(score, 0)
//			sleepDuration := latestTime.Sub(time.Now())
//			//fmt.Println("需要休眠", sleepDuration)
//			// 比如设定10分钟
//			// 每一个预约项都有一个10分钟后要再次检测这个项.
//			// ID:1  TIMEUNIX: 2222
//			// 每次从集合中取出并检测每项的时间戳是否过时了
//			time.Sleep(sleepDuration) //休眠到需要签到的最晚时间
//		}
//		//如果到截至时间还没有签到 , 将该学生添加到违约的list集合中
//		memberArr := strings.Split(member, "/")
//		//如果还能根据这个memberArr 查询到数据 那就说明这个学生违约了
//		exists, err := initialization.Redis.Exists(context.Background(), member).Result()
//		if err != nil {
//			initialization.SeatLogger.Error("initialization.Redis.Exists(context.Background() , member).Result() is failed", zap.Error(err))
//			return
//		}
//
//		studentId := memberArr[1] //拿到学生的id
//		//修改这条预约状态为违约 根据学生id 和 预约开始的时间
//		startTime := memberArr[2] //预约开始时间
//		fmt.Println("预约开始时间", startTime)
//		if exists == 1 {
//			fmt.Println("违约")
//			//存在即违约
//			initialization.DB.Debug().Model(&model.Reserve{}).Where("student_id = ? and appointment_time_start = ?", studentId, startTime).Update("reserve_status", 2) //修改预约状态
//			initialization.Redis.LPush(context.Background(), violatePrefix+"-"+studentId, time.Now().Unix())
//			//删除redis中存储的学生的预约信息
//			initialization.Redis.Del(context.Background(), member)
//			//创建一个list集合,如果该学生违约,插入一次违约记录 , 插入之后检查学生list集合的长度是否大于3
//			if initialization.Redis.LLen(context.Background(), violatePrefix+"-"+studentId).Val() >= 3 {
//				initialization.SeatLogger.Debug("学生违约" + studentId)
//				//禁用该学生两周 并且删除该list集合
//				initialization.Redis.Del(context.Background(), violatePrefix+"-"+studentId)
//				//修改数据库中的学生状态
//				now := time.Now()
//				//计算两周后的时间
//				twoWeeksLater := now.AddDate(0, 0, 14)
//				violateStudentInformation, err := studentService.ViolateStudent(studentId, now, twoWeeksLater)
//				if err != nil {
//					initialization.SeatLogger.Error("studentService.ViolateStudent(studentId , now , twoWeeksLater) is failed", zap.Error(err))
//				}
//				initialization.SeatLogger.Info("违约学生信息", zap.Any("violate", violateStudentInformation))
//			}
//		} else {
//			//不存在说明学生已经签到 标记预约记录正常使用即可
//			fmt.Println("预约开始时间", startTime)
//			initialization.DB.Model(&model.Reserve{}).Where("student_id = ? and appointment_time_start = ?", studentId, startTime).Update("reserve_status", 1) //修改预约状态
//		}
//	}
//}
